home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 November / EnigmA AMIGA RUN 02 (1995)(G.R. Edizioni)(IT)[!][issue 1995-11][Skylink CD].iso / earcd / program / misc / lvodump.lha / LVODump.p < prev    next >
Text File  |  1995-08-31  |  15KB  |  538 lines

  1. { ************************************************************************ }
  2. { ************************************************************************ }
  3. { **************************                    ************************** }
  4. { ************************ }  PROGRAM LVODump;  { ************************ }
  5. { **************************                    ************************** }
  6. { ************************************************************************ }
  7. { ************************************************************************ }
  8. { **                                                                    ** }
  9. { **  This programs prints to standard output a list of Library Vectors ** }
  10. { **  Offsets for the library specified as the parameter,  in a format  ** }
  11. { **  very similar to that of RKM: Libraries and Devices, appendix D.   ** }
  12. { **                                                                    ** }
  13. { **  The .fd file can be specified without the complete path if it is  ** }
  14. { **  either in the current directory or in the fd: logical volume.     ** }
  15. { **                                                                    ** }
  16. { ************************************************************************ }
  17. { **                                                                    ** }
  18. { **                    Created by  Marco Favaretto                     ** }
  19. { **            -------------------------------------------             ** }
  20. { **                   Compiled with KickPascal 2.10                    ** }
  21. { **                                                                    ** }
  22. { ************************************************************************ }
  23. { **                                                                    ** }
  24. { **  History:                                                          ** }
  25. { **                                                                    ** }
  26. { **  950831    1.0     First release                                   ** }
  27. { **                                                                    ** }
  28. { ************************************************************************ }
  29. { ************************************************************************ }
  30.  
  31.  
  32. {$OPT A-,B-,I-,S-,T-}                   { all compiler options off         }
  33.  
  34.  
  35. CONST
  36.         YES = TRUE;                     { boolean value                    }
  37.         NO = FALSE;                     { boolean value                    }
  38.  
  39.         HEAD = 1;                       { see RemoveSpaces()               }
  40.         TAIL = 2;                       { see RemoveSpaces()               }
  41.  
  42.         BIASSTEP = 6;                   { bias step, right!                }
  43.  
  44.         SPACE = ' ';                    { word & output columns separator  }
  45.         TAB   = #$09;                   { output columns separator         }
  46.         LF    = #$0A;                   { input terminator                 }
  47.         COMMA = ',';                    { template separator               }
  48.         COLON = ':';                    { template/option list separator   }
  49.         SLASH = '/';                    { template separator               }
  50.         POINT = '.';                    { option list terminator           }
  51.  
  52.         EMPTYSTRING = '';
  53.         MAXSTRLEN = 255;
  54.  
  55.         TEMPLATEREQUEST = '?';          { user request for template        }
  56.  
  57.  
  58. TYPE
  59.  
  60. { ___ IMPORTANT: do not modify the order of ErrorType options, because ___ }
  61. { ___            doing so will alter the errorcodes of the program     ___ }
  62.  
  63.         ErrorType = (SYNTAX, NOFILENAME, FILENOTFOUND, NOBIAS, INVALIDBIAS,
  64.                      UNKNOWNDIRECTIVE);
  65.  
  66. { ___ IMPORTANT: do not modify the order of ParamType and DirectiveType __ }
  67. { ___            options; otherwise, you MUST modify the related string __ }
  68. { ___            definition in LVODumpSupport.s in the same way.        __ }
  69.  
  70.         ParamType = (UNKNOWN_PAR, FILENAME_PAR, NOTAB_PAR, NOHEADER_PAR,
  71.                      NOBASE_PAR, NOPRIVATE_PAR);
  72.  
  73.         DirectiveType = (UNKNOWN_DIR, BASE_DIR, BIAS_DIR, PRIVATE_DIR,
  74.                          PUBLIC_DIR, END_DIR);
  75.  
  76.         InString = string[MAXSTRLEN];   { for readln from text files, so   }
  77.                                         { the length is no longer limited  }
  78.                                         { to 80 chars per line             }
  79.  
  80. VAR
  81.         InFile:       TEXT;             { .fd file in input                }
  82.         InLine:       InString;         { a line from input file           }
  83.         FName:        string;           { .fd file name                    }
  84.         Bias:         long;             { library vector offset counter    }
  85.         BaseName:     string;           { name of library base             }
  86.         Separator:    char;             { column separator                 }
  87.         PrintHeader:  boolean;          { flag for output header           }
  88.         PrintBase:    boolean;          { flag for output basename         }
  89.         PrintPrivate: boolean;          { flag for private LVO output      }
  90.         HeaderOut:    boolean;          { flag for header (NOT) printed    }
  91.         IsPublic:     boolean;          { flag for private LVO             }
  92.  
  93. { ___ Following vars are uses as Typed Constants with predefined values __ }
  94. { ___ (look at LVODumpSupport.s)                                        __ }
  95.  
  96.         CTEMPLATE:    string;  IMPORT;  { COMMA + command template         }
  97.         TEMPLATE:     string;  IMPORT;  { command template                 }
  98.         CDIRECTIVES:  string;  IMPORT;  { COMMA + list of .fd directives   }
  99.         DIRECTIVES:   string;  IMPORT;  { list of .fd directives           }
  100.         FNAMEEND:     string;  IMPORT;  { the .fd files ends this way      }
  101.         FDPATH:       string;  IMPORT;  { logical volume for .fd. files    }
  102.         BANNER:       string;  IMPORT;  { copyright message and syntax     }
  103.  
  104.  
  105. {$LINK 'LVODumpSupport.o'}
  106.  
  107. PROCEDURE UpCaseStr(VAR a0:InString); EXTERNAL;
  108.  
  109.  
  110. { ___ Output error message and terminate program _________________________ }
  111. { ________________________________________________________________________ }
  112.  
  113. PROCEDURE ShowError(er: ErrorType);
  114.  
  115. VAR
  116.         s: InString;
  117.  
  118. Begin
  119.  
  120.    CASE er OF
  121.  
  122.          SYNTAX:           write(BANNER);
  123.          NOFILENAME:       write('Missing filename.');
  124.          FILENOTFOUND:     write('File not found: ' + FName);
  125.          NOBIAS:           write(FName + ': missing bias directive.');
  126.          INVALIDBIAS:      write(FName + ': invalid bias value.');
  127.          UNKNOWNDIRECTIVE: write(FName + ': unknown directive.')
  128.  
  129.       End;
  130.  
  131.    IF er > FILENOTFOUND THEN    { in this case (only) InFile is open       }
  132.       Close(InFile);
  133.  
  134.    Halt(ord(er) + 21)           { exit error code                          }
  135.  
  136. End;
  137.  
  138.  
  139. { ___ Remove head and tail spaces from a string __________________________ }
  140. { ________________________________________________________________________ }
  141.  
  142. FUNCTION RemoveSpaces(s:InString, Where:byte): InString;
  143.  
  144. VAR
  145.         First, Last: byte;
  146.  
  147. Begin
  148.    First := 1;
  149.    IF (Where AND HEAD) = HEAD THEN
  150.       WHILE (s[First] IN [SPACE, TAB]) DO
  151.          Inc(First);
  152.  
  153.    Last := length(s);
  154.    IF (Where AND TAIL) = TAIL THEN
  155.       WHILE (Last >= First) AND (s[Last] IN [SPACE, TAB, LF]) DO
  156.          Dec(Last);
  157.  
  158.    RemoveSpaces := copy(s, First, Last-First+1)
  159. End;
  160.  
  161.  
  162. { ___ Extract (and possibly remove) the first word from a string _________ }
  163. { ________________________________________________________________________ }
  164.  
  165. FUNCTION GetFirstWord(VAR s:InString, cut:boolean): InString;
  166.  
  167. VAR
  168.         z: byte;
  169.  
  170. Begin
  171.    z := pos(SPACE,s);
  172.    IF z = 0 THEN Begin
  173.  
  174.       z := pos(TAB,s);
  175.       IF z = 0 THEN
  176.          z := length(s) + 1
  177.  
  178.       End;
  179.  
  180.    GetFirstWord := copy(s,1,z-1);
  181.  
  182.    IF cut THEN
  183.       s := RemoveSpaces(copy(s,z,MAXSTRLEN), HEAD)
  184.  
  185. End;
  186.  
  187.  
  188. { ___ Convert a long to hexadecimal string of p chars ____________________ }
  189. { ________________________________________________________________________ }
  190.  
  191. FUNCTION Hex(n:long, p:byte):string;
  192.  
  193. CONST
  194.         HEXDIGITS='0123456789ABCDEF';
  195.  
  196. VAR
  197.         s: string[9];
  198.         z: byte;
  199.  
  200. Begin
  201.    z := 9;
  202.    s := '000000000';
  203.  
  204.    WHILE n > 0 DO Begin
  205.       Dec(z);
  206.       s[z] := HEXDIGITS.[(n MOD 16)+1];
  207.       n := n DIV 16
  208.       End;
  209.  
  210.    Hex := copy(s,9-p,p)
  211. End;
  212.  
  213.  
  214. { ___ Compare an option (string) with a list of options __________________ }
  215. { ________________________________________________________________________ }
  216.  
  217. FUNCTION CheckOption(Pattern: string; Opt:InString): integer;
  218.  
  219. VAR
  220.         z:   byte;
  221.         s:   string;
  222.         p_s: str;
  223.         c:   integer;
  224.  
  225. Begin
  226.  
  227.    c := 0;
  228.  
  229.    s := COMMA + Opt + SLASH;
  230.    z := pos(s, Pattern);
  231.    IF z = 0 THEN Begin
  232.  
  233.       s := COMMA + Opt + COMMA;
  234.       z := pos(s, Pattern);
  235.       IF z = 0 THEN Begin
  236.  
  237.          s := COMMA + Opt + COLON;
  238.          z := pos(s, Pattern);
  239.          IF z = 0 THEN Begin
  240.  
  241.             s := COMMA + Opt + POINT;
  242.             z := pos(s, Pattern);
  243.             IF z = 0 THEN Begin
  244.  
  245.                CheckOption := c;
  246.                Exit
  247.                End
  248.  
  249.             End
  250.  
  251.          End
  252.  
  253.       End;
  254.  
  255.    s := copy(Pattern, 1, z-1);
  256.    p_s := s;
  257.  
  258.    REPEAT
  259.       Inc(c);
  260.       z := pos(COMMA, p_s);
  261.       p_s := str(long(p_s)+z)
  262.    UNTIL z = 0;
  263.  
  264.    CheckOption := c
  265.  
  266. End;
  267.  
  268.  
  269. { ___ Compare each parameter on command line with template _______________ }
  270. { ________________________________________________________________________ }
  271.  
  272. FUNCTION CheckParameter(Param: InString): ParamType;
  273.  
  274. VAR
  275.         z:  integer;
  276.         cp: ParamType;
  277.  
  278. Begin
  279.  
  280.    UpCaseStr(Param);
  281.    z := CheckOption(CTEMPLATE, Param);
  282.    
  283.    cp := UNKNOWN_PAR;
  284.    WHILE z > 0 DO Begin
  285.       cp := succ(cp);
  286.       Dec(z)
  287.       End;
  288.  
  289.    CheckParameter := cp
  290.  
  291. End;
  292.  
  293.  
  294. { ___ Analyse the parameter line _________________________________________ }
  295. { ________________________________________________________________________ }
  296.  
  297. PROCEDURE AnalyzeParameterLine;
  298.  
  299.  
  300. VAR
  301.         ParmLine: InString;
  302.         Param:    InString;
  303.  
  304. Begin
  305.    ParmLine := RemoveSpaces(copy(parameterstr,1,parameterlen), HEAD + TAIL);
  306.  
  307.    IF ParmLine = EMPTYSTRING THEN
  308.       ShowError(NOFILENAME);
  309.  
  310. {$OPT B+}                               { let the user break from here...  }
  311.  
  312.    WHILE ParmLine = TEMPLATEREQUEST DO Begin
  313.  
  314.       write(TEMPLATE);
  315.       readln(ParmLine);
  316.       ParmLine := RemoveSpaces(ParmLine, HEAD + TAIL)
  317.       End;
  318.  
  319. {$OPT B-}                               { ...to here.                      }
  320.  
  321.    WHILE ParmLine > EMPTYSTRING DO Begin
  322.       Param := GetFirstWord(ParmLine, YES);
  323.       CASE CheckParameter(Param) OF
  324.  
  325.             UNKNOWN_PAR:   IF FName = '' THEN
  326.                                  FName := Param
  327.                               ELSE
  328.                                  ShowError(SYNTAX);
  329.  
  330.             FILENAME_PAR:  IF FName = '' THEN
  331.                                 FName := GetFirstWord(ParmLine, YES)
  332.                              ELSE
  333.                                 ShowError(SYNTAX);
  334.  
  335.             NOTAB_PAR:     Separator := SPACE;
  336.  
  337.             NOHEADER_PAR:  PrintHeader := NO;
  338.  
  339.             NOBASE_PAR:    PrintBase := NO;
  340.  
  341.             NOPRIVATE_PAR: PrintPrivate := NO
  342.  
  343.          End { CASE }
  344.  
  345.       End; { WHILE }
  346.  
  347.    IF FName = EMPTYSTRING THEN
  348.       ShowError(NOFILENAME)
  349.  
  350. End;
  351.  
  352.  
  353. { ___ Extract Bias value from a ##bias directive _________________________ }
  354. { ________________________________________________________________________ }
  355.  
  356. FUNCTION GetBias(s:InString): long;
  357.  
  358. VAR
  359.         err: integer;
  360.         v:   long;
  361.  
  362. Begin
  363.    Val(s, v, err);
  364.    IF err <> 0 THEN
  365.       ShowError(INVALIDBIAS);
  366.    GetBias := v
  367. End;
  368.  
  369.  
  370. { ___ Compare each directive in InLine with directives list ______________ }
  371. { ________________________________________________________________________ }
  372.  
  373. FUNCTION CheckDirective(Dir: InString): DirectiveType;
  374.  
  375. VAR
  376.         z:  integer;
  377.         cd: DirectiveType;
  378.  
  379. Begin
  380.  
  381.    UpCaseStr(Dir);
  382.    z := CheckOption(CDIRECTIVES, Dir);
  383.    
  384.    cd := UNKNOWN_DIR;
  385.    WHILE z > 0 DO Begin
  386.       cd := succ(cd);
  387.       Dec(z)
  388.       End;
  389.  
  390.    CheckDirective := cd
  391.  
  392. End;
  393.  
  394.  
  395. { ___ Analyse each line and produce output _______________________________ }
  396. { ________________________________________________________________________ }
  397.  
  398. PROCEDURE ProcessLine(s:InString);
  399.  
  400. VAR
  401.         z: byte;
  402.  
  403. Begin
  404.    CASE s[1] OF
  405.  
  406.          '*': ;
  407.  
  408.          '#': CASE CheckDirective(GetFirstWord(s, YES)) OF
  409.  
  410.                     BIAS_DIR:    bias := GetBias(s);
  411.  
  412.                     BASE_DIR:    IF PrintBase THEN
  413.                                     BaseName := s;
  414.  
  415.                     PUBLIC_DIR:  IsPublic := YES;
  416.  
  417.                     PRIVATE_DIR: IsPublic := NO;
  418.  
  419.                     END_DIR:     ;
  420.  
  421.                     UNKNOWN_DIR: ShowError(UNKNOWNDIRECTIVE)
  422.  
  423.                  End;
  424.  
  425.       OTHERWISE Begin
  426.  
  427.          IF Bias = MAXLONGINT THEN
  428.             ShowError(NOBIAS);
  429.  
  430.          IF (NOT HeaderOut) AND PrintHeader THEN Begin
  431.  
  432.             HeaderOut := YES;
  433.  
  434.             z := pos(FNAMEEND, FName);
  435.             IF z<>0 THEN
  436.                   write(copy(FName,1,z-1))
  437.                ELSE
  438.                   write(FName);
  439.  
  440.             write(' Library Vectors Offsets');
  441.  
  442.             IF (BaseName <> EMPTYSTRING) AND PrintBase THEN
  443.                   writeln('   (Base name: ',BaseName,')')
  444.                ELSE
  445.                   writeln
  446.  
  447.             End;
  448.             
  449.          IF PrintPrivate OR IsPublic THEN Begin
  450.             write(Bias:4,Separator,'$',Hex(65536-Bias,4),Separator);
  451.             writeln('-$',Hex(Bias,4),Separator,s)
  452.             End;
  453.  
  454.          Bias := Bias + BIASSTEP
  455.          End
  456.  
  457.       End
  458.  
  459. End;
  460.  
  461.  
  462. { ___ Open input file and do the real work _______________________________ }
  463. { ________________________________________________________________________ }
  464.  
  465. PROCEDURE ProcessFile;
  466.  
  467. Begin
  468.  
  469. { ___ Try to open file ___________________________________________________ }
  470.  
  471.    Assign(InFile, FName);
  472.    Reset(InFile);
  473.    IF IOResult <> 0 THEN Begin
  474.  
  475.       Assign(InFile, FName + FNAMEEND);
  476.       Reset(InFile);
  477.       IF IOResult <> 0 THEN Begin
  478.  
  479.          Assign(InFile, FDPATH + FName);
  480.          Reset(InFile);
  481.          IF IOResult <> 0 THEN Begin
  482.  
  483.             Assign(InFile, FDPATH + FName + FNAMEEND);
  484.             Reset(InFile);
  485.             IF IOResult <> 0 THEN
  486.  
  487.                ShowError(FILENOTFOUND);
  488.  
  489.             End
  490.          End
  491.       End;
  492.  
  493.  
  494. {$OPT B+}                               { the user can break from here     }
  495.  
  496. { ___ Scan file line by line, producing output ___________________________ }
  497.  
  498.    REPEAT                               { Note that readln set EOF to TRUE }
  499.       readln(InFile,InLine);            { when it reads the last line from }
  500.       ProcessLine(InLine)               { the file, and not when it tries  }
  501.    UNTIL EOF(InFile);                   { to read the (unexisting) next.   }
  502.  
  503. {$OPT B-}                               { the user needs to break no more  }
  504.  
  505.    Close(InFile)
  506.  
  507. End;
  508.  
  509.  
  510. { ___ Set up the global variables ________________________________________ }
  511. { ________________________________________________________________________ }
  512.  
  513. PROCEDURE SetUpVars;
  514.  
  515. Begin
  516.    Bias := MAXLONGINT;
  517.    FName := EMPTYSTRING;
  518.    BaseName := EMPTYSTRING;
  519.  
  520.    PrintHeader := YES;
  521.    PrintBase := YES;
  522.    PrintPrivate := YES;
  523.    Separator := TAB;
  524.  
  525.    HeaderOut := NO;
  526.    IsPublic := YES
  527. End;
  528.  
  529.  
  530. { ___ Main program _______________________________________________________ }
  531. { ________________________________________________________________________ }
  532.  
  533. Begin
  534.    SetUpVars;
  535.    AnalyzeParameterLine;
  536.    ProcessFile
  537. End.
  538.